package com.example.mybaseapp.widget.my_circle_seekbar

import android.graphics.Rect
import java.lang.Float.max
import java.lang.Float.min
import kotlin.math.abs
import kotlin.math.atan2
import kotlin.properties.Delegates


class CircleUtil {

    /**指针与刻度线的角度误差值*/
    var errorDegreeRange by Delegates.notNull<Float>()
    /**触控指针的范围值*/
    val touchRange = 30
    /**放手后自动移动的弧度*/
    var upMoveDegreeRange =0F
    /**差距清空判断*/
    var upMoveDegreeRangeFlag = false
    /**判断当前是否是放手之后的
     * 放手之后，需要返回选中值*/
    var isUpNow = false
    /**选中值的监听*/
    var mSelectListener:SelectListener?=null
    /** 初始角度*/
    var startDegree = 0.0

    /**是否可以移动 true-是*/
    var canMove = false

    fun resetMoveState(){
        upMoveDegreeRangeFlag = false
        upMoveDegreeRange = 0F
    }

    fun endMoveState(){
        if(!upMoveDegreeRangeFlag){
            upMoveDegreeRange = 0F
        }
        upMoveDegreeRangeFlag = false
        println("endMoveState $upMoveDegreeRange")
    }

    /**
     * 判断两个角度是否处于误差范围
     * @param degree1 刻度的角度
     * @param degree2 指针的角度
     */
    fun areDegreesClose(degree1: Float, degree2: Float): Boolean {
        // 计算角度差
        var diff =  degree1 - degree2
        if(diff>360){
            diff %= 360
        }else if(diff<-360){
            diff %= -360
        }

        if(diff <= errorDegreeRange && diff>-errorDegreeRange){
//            记录放手后要自动滑动的角度
            upMoveDegreeRangeFlag = true
            upMoveDegreeRange = diff
            println("Fireg degree1=$degree1 degree2=$degree2")
            println("Fireg diff=$diff errorDegreeRange:$errorDegreeRange")
            return true
        }
        return false
    }

    /**
     * 触发选中值的返回
     */
    fun hasSelectListener(value:PointsData){
        if(isUpNow) {
            mSelectListener?.selectPoint(value.value)
            isUpNow = false
        }
    }

    /**
     * 两个角度相加
     * 并控制角度范围不能超过360度，小于-360
     */
    private fun degreeAddDegree(degree1:Float, degree2: Float):Float{
        var dTmp = degree1 + degree2
        if(dTmp>360) { dTmp %= 360}
        if(dTmp<-360){dTmp %= -360}
        return dTmp
    }

    /**
     * 两个角度相减
     */
    private fun degreeSubDegree(degree1:Float, degree2: Float):Float{
        var dTmp = degree1 - degree2
        if(dTmp>360) { dTmp %= 360}
        if(dTmp<-360){dTmp %= -360}
        return dTmp
    }

    /**
     * 多个角度相加
     */
    fun degreeAdd(vararg degrees:Float):Float{
        var dTmp = 0F
        for(d in degrees){
            dTmp = degreeAddDegree(dTmp,d)
        }
        return dTmp
    }

    /**
     * 多个角度相减
     */
    fun degreeSub(vararg degrees:Float):Float{
        var dTmp = 0F
        for(i in degrees.indices){
            dTmp = if(i==0){
                degrees[0]
            }else{
                degreeSubDegree(dTmp,degrees[i])
            }
        }
        return dTmp
    }

    // 计算角度，确保角度范围在 [-360, 360]
    fun calculateAngle(x: Float, y: Float, centerX: Float, centerY: Float, touchStartX: Float, touchStartY: Float): Float {
        return Math.toDegrees(atan2((y - centerY).toDouble(), (x - centerX).toDouble())
                - atan2((touchStartY - centerY).toDouble(), (touchStartX - centerX).toDouble())).toFloat().let { angle ->
            val normalizedAngle = if (angle >= 0) angle else angle + 360
            if (normalizedAngle > 360) normalizedAngle % 360 else normalizedAngle
        }
    }

    fun calculateAngle1(x: Float, y: Float, centerX: Float, centerY: Float, touchStartX: Float, touchStartY: Float):Float{
         var degree = Math.toDegrees(atan2((y - centerY).toDouble(), (x - centerX).toDouble())
                - atan2((touchStartY - centerY).toDouble(), (touchStartX - centerX).toDouble()))
            .toFloat()

        return degree
    }

    /**
     * 判断点击是否在指针范围内
     * 【这个使用了大概的值，毕竟指针比较小，还是要扩大触控范围的，就不用太在乎触控范围的大小是否是真实形状
     *
     * @param touchRange 触控范围
     */
     fun isContainSelectLine(touchX:Float, touchY:Float, selectBottomX:Float,selectTopX:Float, selectBottomY:Float, selectTopY:Float):Boolean{
        val xMin:Float = min(selectBottomX,selectTopX)
        val xMax:Float = max(selectBottomX,selectTopX)
        val yMin = min(selectBottomY,selectTopY)
        val yMax = max(selectBottomY,selectTopY)
        return touchX>xMin-touchRange && touchX< xMax+touchRange && touchY>yMin-touchRange && touchY<yMax+touchRange
    }

//    fun move(x: Float,y: Float,radius:Float, lineDegree:Float):Float{
//        var arcRadians:Float
//        if(y>0){
//            arcRadians = (x-currentX)/abs(radius - y)
//        }else{
//            arcRadians = (x-currentX)/abs(y - radius)
//        }
//        val step = arcRadians*lineDegree /3.14
//        currentDegree+= step.toFloat()
//        currentX = x
//        return currentDegree
//    }

//    fun

}